package com.vtuzx.kingdee.xqc_api.service.impl;

import com.vtuzx.core.VtuzxException;
import com.vtuzx.core.bean.dto.VtuzxMap;
import com.vtuzx.core.bean.dto.VtuzxPage;
import com.vtuzx.core.bean.dto.VtuzxToken;
import com.vtuzx.core.constant.IVtuzxConst;
import com.vtuzx.core.file.excel.VtuzxExcel;
import com.vtuzx.core.file.excel.VtuzxExcelCell;
import com.vtuzx.core.file.excel.VtuzxExcelRow;
import com.vtuzx.core.file.excel.VtuzxExcelSheet;
import com.vtuzx.core.utils.VtuzxUtil;
import com.vtuzx.fast.utils.FastUtil;
import com.vtuzx.kingdee.xqc_api.service.IXqcConfigService;
import com.vtuzx.kingdee.xqc_core.bean.VtuzxArrayList;
import com.vtuzx.kingdee.xqc_core.constant.BillType;
import com.vtuzx.kingdee.xqc_core.constant.ConfigType;
import com.vtuzx.kingdee.xqc_core.dao.KingdeePushRuleDao;
import com.vtuzx.kingdee.xqc_core.dao.StoreTokenDao;
import com.vtuzx.web.bean.VtuzxDownloadBean;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class XqcConfigServiceImpl implements IXqcConfigService {

    /** 配置DAO */
    @Autowired
    private StoreTokenDao storeTokenDao;

    /** 下推规则DAO */
    @Autowired
    private KingdeePushRuleDao pushRuleDao;

    @Override
    public VtuzxDownloadBean downloadBillBarcode(BillType billType, List<VtuzxMap> detailList) throws Exception {

        String timestamp = new SimpleDateFormat("yyMMddHHmmss").format(new Date());

        List<VtuzxExcelSheet> sheets = new ArrayList<>();
        VtuzxExcelSheet sheet0 = new VtuzxExcelSheet(0, "二维码列表");
        int col = 0;
        int row = 0;
        VtuzxExcelRow header0 = new VtuzxExcelRow(row++, new VtuzxArrayList<>(
                new VtuzxExcelCell(col++, "二维码信息"),
                new VtuzxExcelCell(col++, "产品名称"),
                new VtuzxExcelCell(col++, "产品编码"),
                new VtuzxExcelCell(col++, "规格型号"),
                new VtuzxExcelCell(col++, "批次号"),
                new VtuzxExcelCell(col++, "单位"),
                new VtuzxExcelCell(col++, "件数"),
                new VtuzxExcelCell(col++, "总重"),
                new VtuzxExcelCell(col++, "数量"),
                new VtuzxExcelCell(col++, "备注"),
                new VtuzxExcelCell(col++, "供应商"),
                new VtuzxExcelCell(col++, "入库时间"),
                new VtuzxExcelCell(col++, "生产时间"),
                new VtuzxExcelCell(col++, "保质期"),
                new VtuzxExcelCell(col++, "保质期至"),
                new VtuzxExcelCell(col++, "箱号"),
                new VtuzxExcelCell(col++, "备注"),
                new VtuzxExcelCell(col,"追溯码")
        ));
        sheet0.addRow(header0);

        for(VtuzxMap detail: detailList) {
            VtuzxMap header = VtuzxUtil.getObject(detail, "header");
            int boxCount = VtuzxUtil.getInt(header, "boxCount");
            double sumCount = VtuzxUtil.getDouble(header, "count");
            List<VtuzxMap> boxList = VtuzxUtil.getObject(detail, "boxList");
            String produceDate = VtuzxUtil.getString(header, "produceDate");
            int exp = VtuzxUtil.getInt(header, "exp");
            String comment = "";
            String billNo = VtuzxUtil.getString(header, "billNo");
            if (billNo.startsWith("CJSH") || billNo.startsWith("CGSH")) {
                comment = VtuzxUtil.getString(header, "remark"); //为
            }
            String limitTime = "";
            if (!VtuzxUtil.isEmpty(produceDate)) {
                limitTime = produceDate;
//                limitTime = VtuzxUtil.formatYmdF(VtuzxUtil.calcDate(VtuzxUtil.parseDate(produceDate), Calendar.DATE, exp));
            }
            String materialNo = VtuzxUtil.getString(header, "materialNo");
            String materialName = VtuzxUtil.getString(header, "materialName");
            String materialSpec = VtuzxUtil.getString(header, "materialSpec");
            String batchNo = VtuzxUtil.getString(header, "batchNo");
            String supplierName = VtuzxUtil.getString(header, "supplierName");
            String remark = VtuzxUtil.getString(header,"remark");
            for(VtuzxMap data: boxList) {
                String id = VtuzxUtil.getString(data, "id");
                String count = VtuzxUtil.getString(data, "count");
                String unit = VtuzxUtil.getString(data, "unitName");
                String boxNo = VtuzxUtil.getString(data, "boxNo");
                List<String> traceBack = VtuzxUtil.getObject(data,"traceBack");
                String traceBackStr = "";
                if (!VtuzxUtil.isEmpty(traceBack)){
                    traceBackStr = traceBack.toString();
                }
                if (billNo.startsWith("CJSH") || billNo.startsWith("CGSH")) {
                    comment = VtuzxUtil.getString(data, "comment");
                }
                String perInTime = VtuzxUtil.getString(data, "perInTime");
                String barcode = billType.barcodeKey() + "|;" + id + "|;" + materialNo + "|;" + "888888" + "|;" + count + "|;" + boxNo;
                col = 0;
                VtuzxExcelRow dataRow = new VtuzxExcelRow(row++, new VtuzxArrayList<>(
                        new VtuzxExcelCell(col++, barcode),
                        new VtuzxExcelCell(col++, materialName),
                        new VtuzxExcelCell(col++, materialNo),
                        new VtuzxExcelCell(col++, materialSpec),
                        new VtuzxExcelCell(col++, batchNo),
                        new VtuzxExcelCell(col++, unit),
                        new VtuzxExcelCell(col++, boxCount),
                        new VtuzxExcelCell(col++, sumCount),
                        new VtuzxExcelCell(col++, Double.parseDouble(count)),
                        new VtuzxExcelCell(col++, remark),
                        new VtuzxExcelCell(col++, supplierName),
                        new VtuzxExcelCell(col++, perInTime),
                        new VtuzxExcelCell(col++, produceDate),
                        new VtuzxExcelCell(col++, exp),
                        new VtuzxExcelCell(col++, limitTime),
                        new VtuzxExcelCell(col++, boxNo),
                        new VtuzxExcelCell(col++, comment),
                        new VtuzxExcelCell(col,traceBackStr)
                ));
                sheet0.addRow(dataRow);
            }
        }

        sheet0.setColumnWidth(new VtuzxArrayList<>(
                new int[] { 0, 850 },
                new int[] { 1, 200 },
                new int[] { 2, 200 },
                new int[] { 3, 200 },
                new int[] { 4, 200 },
                new int[] { 5, 150 },
                new int[] { 6, 150 },
                new int[] { 7, 150 },
                new int[] { 8, 150 },
                new int[] { 9, 150 },
                new int[] { 10, 150 },
                new int[] { 11, 150 },
                new int[] { 12, 250 },
                new int[] { 13, 250 }
        ));

        sheets.add(sheet0);
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        VtuzxExcel.write(stream, sheets);
        return new VtuzxDownloadBean(billType.label() + "二维码" + timestamp + ".xlsx", stream);
    }

//    @Override
//    public VtuzxDownloadBean downloadBillBarcode(BillType billType, VtuzxMap header, List<VtuzxMap> boxList) throws Exception {
//
//        String timestamp = new SimpleDateFormat("yyMMddHHmmss").format(new Date());
//
//        List<VtuzxExcelSheet> sheets = new ArrayList<>();
//        VtuzxExcelSheet sheet0 = new VtuzxExcelSheet(0, "二维码列表");
//        int col = 0;
//        int row = 0;
//        VtuzxExcelRow header0 = new VtuzxExcelRow(row++, new VtuzxArrayList<>(
//                new VtuzxExcelCell(col++, "二维码信息"),
//                new VtuzxExcelCell(col++, "产品名称"),
//                new VtuzxExcelCell(col++, "产品编码"),
//                new VtuzxExcelCell(col++, "规格型号"),
//                new VtuzxExcelCell(col++, "批次号"),
//                new VtuzxExcelCell(col++, "单位"),
//                new VtuzxExcelCell(col++, "数量"),
//                new VtuzxExcelCell(col++, "供应商"),
//                new VtuzxExcelCell(col++, "入库时间"),
//                new VtuzxExcelCell(col++, "生产时间"),
//                new VtuzxExcelCell(col++, "保质期"),
//                new VtuzxExcelCell(col++, "保质期至"),
//                new VtuzxExcelCell(col, "箱号"),
//                new VtuzxExcelCell(col, "备注")
//        ));
//        sheet0.addRow(header0);
//        String produceDate = VtuzxUtil.getString(header, "produceDate");
//        int exp = VtuzxUtil.getInt(header, "exp");
//        String limitTime = "";
//        if (!VtuzxUtil.isEmpty(produceDate)) {
//            limitTime = VtuzxUtil.formatYmdF(VtuzxUtil.calcDate(VtuzxUtil.parseDate(produceDate), Calendar.DATE, exp));
//        }
//        String materialNo = VtuzxUtil.getString(header, "materialNo");
//        String materialName = VtuzxUtil.getString(header, "materialName");
//        String materialSpec = VtuzxUtil.getString(header, "materialSpec");
//        String batchNo = VtuzxUtil.getString(header, "batchNo");
//        String supplierName = VtuzxUtil.getString(header, "supplierName");
//        for(VtuzxMap data: boxList) {
//            String id = VtuzxUtil.getString(data, "id");
//            String count = VtuzxUtil.getString(data, "count");
//            String unit = VtuzxUtil.getString(data, "unit");
//            String boxNo = VtuzxUtil.getString(data, "boxNo");
//            String comment = VtuzxUtil.getString(data, "comment");
//            String perInTime = VtuzxUtil.getString(data, "perInTime");
//            String barcode = billType.barcodeKey() + "|;" + id + "|;" + materialNo + "|;" + batchNo + "|;" + count + "|;" + boxNo;
//            col = 0;
//            VtuzxExcelRow dataRow = new VtuzxExcelRow(row++, new VtuzxArrayList<>(
//                    new VtuzxExcelCell(col++, barcode),
//                    new VtuzxExcelCell(col++, materialName),
//                    new VtuzxExcelCell(col++, materialNo),
//                    new VtuzxExcelCell(col++, materialSpec),
//                    new VtuzxExcelCell(col++, batchNo),
//                    new VtuzxExcelCell(col++, unit),
//                    new VtuzxExcelCell(col++, Double.parseDouble(count)),
//                    new VtuzxExcelCell(col++, supplierName),
//                    new VtuzxExcelCell(col++, perInTime),
//                    new VtuzxExcelCell(col++, produceDate),
//                    new VtuzxExcelCell(col++, exp),
//                    new VtuzxExcelCell(col++, limitTime),
//                    new VtuzxExcelCell(col, boxNo),
//                    new VtuzxExcelCell(col, comment)
//            ));
//            sheet0.addRow(dataRow);
//        }
//        sheet0.setColumnWidth(new VtuzxArrayList<>(
//                new int[] { 0, 850 },
//                new int[] { 1, 200 },
//                new int[] { 2, 200 },
//                new int[] { 3, 200 },
//                new int[] { 4, 200 },
//                new int[] { 8, 150 },
//                new int[] { 9, 150 },
//                new int[] { 11, 150 }
//        ));
//
//        sheets.add(sheet0);
//        ByteArrayOutputStream stream = new ByteArrayOutputStream();
//        VtuzxExcel.write(stream, sheets);
//        return new VtuzxDownloadBean(billType.label() + "二维码" + timestamp + ".xlsx", stream);
//    }

    @Override
    public void updateKingdeeConfig(VtuzxToken token, Map<String, Object> param) {
        storeTokenDao.updateKingdee(new Document(param));
    }

    @Override
    public VtuzxMap getKingdeeConfig(VtuzxToken token) {
        VtuzxMap res = new VtuzxMap();
        Document storeToken = storeTokenDao.findOne(Criteria.where("type").is(ConfigType.Kingdee.toString()));
        storeToken.remove(IVtuzxConst.Key__id);
        storeToken.remove(IVtuzxConst.Key_createTime);
        storeToken.remove(IVtuzxConst.Key_updateTime);
        res.append(ConfigType.Kingdee.toString(), new VtuzxMap(storeToken));
        return res;
    }

    @Override
    public void addPushRule(VtuzxToken token, Map<String, Object> param) throws Exception {
        pushRuleDao.insertOne(createPushRule(param));
    }

    @Override
    public void deletePushRules(VtuzxToken token, List<String> ids) throws Exception {
        pushRuleDao.deleteMany(Criteria.where(IVtuzxConst.Key__id).in(FastUtil.convertId(ids)));
    }

    @Override
    public void updatePushRule(VtuzxToken token, Map<String, Object> param) throws Exception {
        String id = VtuzxUtil.getString(param, "id");
        if (VtuzxUtil.isEmpty(id)) {
            throw new VtuzxException(IVtuzxConst.Msg_E_target_not_exist);
        }
        pushRuleDao.updateById(id, createPushRule(param));
    }

    @Override
    public VtuzxMap getPushRule(VtuzxToken token, Map<String, Object> param) {
        int pageIndex = VtuzxUtil.getInt(param, IVtuzxConst.Key_pageIndex);
        int pageSize = VtuzxUtil.getInt(param, IVtuzxConst.Key_pageSize, IVtuzxConst.PageSize);
        String formName = VtuzxUtil.getString(param, "formName");
        String formId = VtuzxUtil.getString(param, "formId");
        String effect = VtuzxUtil.getString(param, "effect");
        Criteria cond = new Criteria();
        if (!VtuzxUtil.isEmpty(formName)) {
            cond.and("formName").regex(formName);
        }
        if (!VtuzxUtil.isEmpty(formId)) {
            cond.and("formId").is(formId);
        }
        if (!VtuzxUtil.isEmpty(effect)) {
            cond.and("effect").is("true".equals(effect));
        }
        VtuzxPage page = pushRuleDao.page(cond, new Document(IVtuzxConst.Key_createTime, -1), pageIndex, pageSize);
        if (page.total() == 0) {
            return new VtuzxMap(IVtuzxConst.Key_total, 0).append(IVtuzxConst.Key_data, new ArrayList<>());
        }
        List<VtuzxMap> dataList = page.iterator(doc -> new VtuzxMap("id", VtuzxUtil.getString(doc, IVtuzxConst.Key__id))
                .append("formName", VtuzxUtil.getString(doc, "formName"))
                .append("formId", VtuzxUtil.getString(doc, "formId"))
                .append("ruleId", VtuzxUtil.getString(doc, "ruleId"))
                .append("effect", VtuzxUtil.getBoolean(doc, "effect"))
                .append("comment", VtuzxUtil.getString(doc, "comment"))
                .append("createTime", VtuzxUtil.formatYmdHmF(VtuzxUtil.getObject(doc, "createTime"))));

        return new VtuzxMap(IVtuzxConst.Key_total, page.total()).append(IVtuzxConst.Key_data, dataList);
    }

    /**
     * 创建规则Doc
     *
     * @param param 入参
     * @return 规则Doc
     */
    private Document createPushRule(Map<String, Object> param) {
        Document res = new Document();
        res.append("formName", VtuzxUtil.getString(param, "formName"));
        res.append("formId", VtuzxUtil.getString(param, "formId"));
        res.append("ruleId", VtuzxUtil.getString(param, "ruleId"));
        res.append("effect", VtuzxUtil.getBoolean(param, "effect"));
        res.append("comment", VtuzxUtil.getString(param, "comment"));
        return res;
    }
}
